from django.core.paginator import ObjectPaginator as Paginator
from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext import db
import logging
from django.utils import simplejson
import web

urls = (
  '/', 'index',
  '/twilio', 'serveit',
  '/joke/add', 'addjoke',
  '/joke/page/(\d+)', 'getjokepage',
  '/joke/vote', 'jokevote',
  '/about', 'about',
)

class about:
  def GET(self):
    return template.render("templates/about.html", {})

class Joke(db.Model):
  joke_text = db.TextProperty(required=True)
  date_created = db.DateTimeProperty(auto_now_add=True)
  date_published = db.DateTimeProperty(required=False)
  votes = db.IntegerProperty(required=True)

class VoterJokeMapping(db.Model):
  ip_address = db.StringProperty(required=True)
  joke = db.ReferenceProperty(Joke, required=True)

def get_top_joke_text():
  query = Joke.all()
  query.order("-votes")
  joke = query.get()
  return joke.joke_text

class addjoke:
  def POST(self):
    web.header('Content-Type', 'application/json')
    joke_text = web.input().joke_text
    
    if len(joke_text) == 0:
      return simplejson.dumps({"success":False, "message":"Joke needs at least one character"})
    
    joke = Joke(joke_text=joke_text,
                votes=0)
    key = db.put(joke)

    return simplejson.dumps({"success":True, "message":"Added Joke", "data":{"id":key.id()}})
    
class getjokepage:
  def GET(self, page_number):
    page_number = int(page_number)
    web.header('Content-Type', 'application/json')
    query = Joke.all()
    query.order("-date_created")
    db_jokes = query.fetch(limit=1000)
    joke_list = []
    for j in db_jokes:
      joke_list.append({"id":j.key().id(), "vote_count":j.votes, "joke_text":j.joke_text})
    pager = Paginator(joke_list, 5)

    if page_number >= 1 and page_number <= pager.pages:
      result = {"success":True, "page_number":page_number, "total_pages":pager.pages, "result_set":pager.get_page(page_number-1)}
    else:
      result = {"success":False, "message":"Page does not exist"}

    return simplejson.dumps(result)

class jokevote:
  def POST(self):
    web.header('Content-Type', 'application/json')
    ip_address = web.ctx["ip"]
    input = web.input()
    if not input.has_key("action"):
      return simplejson.dumps({"success":False, "message":"Need to specify an action upvote or downvote"})
    if not input.has_key("joke_id"):
      return simplejson.dumps({"success":False, "message":"Need to specify a joke_id"})
    joke = Joke.get_by_id(int(input.joke_id))
    if joke is None:
      return simplejson.dumps({"success":False, "message":"joke_id does not exist"})
    
    voter_query = VoterJokeMapping.all()
    voter_query.filter("ip_address =", ip_address)
    voter_query.filter("joke =", joke)
    voter_result = voter_query.get()
    if voter_result is not None:
      return simplejson.dumps({"success":False, "message":"Only one vote per joke"})

    voter_map = VoterJokeMapping(ip_address=ip_address, joke=joke)
    db.put(voter_map)
    
    def update_vote_count(j, action):
      if action == "upvote":
        j.votes += 1
      elif action == "downvote":
        j.votes -= 1
        if j.votes <= -10:
          j.delete()
          return
      j.put()

    db.run_in_transaction(update_vote_count, joke, input.action)

    return simplejson.dumps({"success":True, "vote_count":joke.votes})

class serveit:
  def GET(self):
    web.header('Content-Type', 'text/xml')
    text = get_top_joke_text()
    return template.render('templates/twilio_say.xml', {"say":text})
  
  def POST(self):
    return self.GET()

class index:
  def GET(self):
    return template.render('templates/index.html', {})

app = web.application(urls, globals())
main = app.cgirun()
